package com.iot.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.iot.commons.ResponseResult;
import com.iot.enums.StatusEnum;
import com.iot.mapper.DeviceMapper;
import com.iot.model.dto.DeviceDto;
import com.iot.model.entity.DeviceEntity;
import com.iot.model.query.DeviceQuery;
import com.iot.model.vo.AuthInfoVo;
import com.iot.model.vo.DeviceVo;
import com.iot.service.DeviceService;
import com.iot.utils.DateUtil;
import com.iot.utils.ResponseResultUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * DeviceServiceImpl
 *
 * @author: dh
 * @date: 2024-04-20 23:39:54
 */
@Service
@RequiredArgsConstructor
public class DeviceServiceImpl implements DeviceService {

    private final DeviceMapper deviceMapper;

    @Override
    public ResponseResult getList(DeviceQuery device) {
        Page<DeviceEntity> page = new Page<>(device.getPageIndex(), device.getPageSize());
        LambdaQueryWrapper<DeviceEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(DeviceEntity::getState, StatusEnum.VALID.getKey());
        queryWrapper.orderByDesc(DeviceEntity::getCreateTime);
        IPage<DeviceEntity> devicePage = deviceMapper.selectPage(page, queryWrapper);
        List<DeviceVo> deviceVoList = Lists.newArrayList();
        for (DeviceEntity deviceEntity : devicePage.getRecords()) {
            DeviceVo vo = new DeviceVo();
            vo.setId(deviceEntity.getId());
            vo.setMac(deviceEntity.getMac());
            vo.setFirmwareName(deviceEntity.getFirmwareName());
            vo.setFirmwareVer(deviceEntity.getFirmwareVer());
            vo.setDeviceName(deviceEntity.getDeviceName());
            vo.setState(deviceEntity.getState());
            vo.setCreateTime(deviceEntity.getCreateTime());
            vo.setUpdateTime(deviceEntity.getUpdateTime());
            deviceVoList.add(vo);
        }

        return ResponseResultUtil.success(devicePage.getTotal(), deviceVoList);
    }

    @Override
    public ResponseResult edit(DeviceDto device) {
        AuthInfoVo authInfoEntity = (AuthInfoVo) StpUtil.getSession().get("loginInfo");
        if (null == authInfoEntity) {
            return ResponseResultUtil.authInfoFailure();
        }
        LambdaUpdateWrapper<DeviceEntity> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.eq(DeviceEntity::getAuthId,authInfoEntity.getId());
        updateWrapper.eq(DeviceEntity::getState,StatusEnum.VALID.getKey());

        DeviceEntity entity = new DeviceEntity();
        entity.setImei(device.getImei());
        entity.setPhone(device.getPhone());
        entity.setUpdateTime(DateUtil.now());
        deviceMapper.update(entity,updateWrapper);
        return ResponseResultUtil.success();
    }

    @Override
    public ResponseResult bind(DeviceDto device) {
        if (null == device) {
            return ResponseResultUtil.paramFailure();
        }
        String mac = device.getMac();
        if (StringUtils.isEmpty(mac)) {
            return ResponseResultUtil.paramFailure();
        }
        AuthInfoVo authInfoEntity = (AuthInfoVo) StpUtil.getSession().get("loginInfo");
        if (null == authInfoEntity) {
            return ResponseResultUtil.authInfoFailure();
        }

        LambdaQueryWrapper<DeviceEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(DeviceEntity::getAuthId, authInfoEntity.getId());
        queryWrapper.eq(DeviceEntity::getState, StatusEnum.VALID.getKey());
        queryWrapper.last("limit 1");
        DeviceEntity deviceEntity = deviceMapper.selectOne(queryWrapper);

        LambdaUpdateWrapper<DeviceEntity> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.eq(DeviceEntity::getAuthId, authInfoEntity.getId());
        updateWrapper.eq(DeviceEntity::getState, StatusEnum.VALID.getKey());
        DeviceEntity updateEntity = new DeviceEntity();
        updateEntity.setState(StatusEnum.DELETE.getKey());
        deviceMapper.update(updateEntity, updateWrapper);

        DeviceEntity entity = new DeviceEntity();
        entity.setMac(mac);
        if (null != deviceEntity) {
            entity.setImei(deviceEntity.getImei());
            entity.setPhone(deviceEntity.getPhone());
        }
        entity.setFirmwareName(device.getFirmwareName());
        entity.setFirmwareVer(device.getFirmwareVer());
        entity.setDeviceName(device.getDeviceName());
        entity.setState(StatusEnum.VALID.getKey());
        entity.setCreateTime(DateUtil.now());
        entity.setAuthId(authInfoEntity.getId());
        deviceMapper.insert(entity);
        return ResponseResultUtil.success();
    }

    @Override
    public ResponseResult unbind() {
        AuthInfoVo authInfoEntity = (AuthInfoVo) StpUtil.getSession().get("loginInfo");
        if (null == authInfoEntity) {
            return ResponseResultUtil.authInfoFailure();
        }
        Long id = authInfoEntity.getId();
        LambdaUpdateWrapper<DeviceEntity> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(DeviceEntity::getAuthId, id);

        DeviceEntity entity = new DeviceEntity();
        entity.setState(StatusEnum.DELETE.getKey());
        entity.setUpdateTime(DateUtil.now());
        deviceMapper.update(entity, wrapper);
        return ResponseResultUtil.success();
    }

    @Override
    public ResponseResult getById(DeviceQuery device) {
        DeviceEntity deviceEntity = deviceMapper.selectById(device.getId());
        DeviceVo vo = new DeviceVo();
        vo.setId(deviceEntity.getId());
        vo.setMac(deviceEntity.getMac());
        vo.setFirmwareName(deviceEntity.getFirmwareName());
        vo.setFirmwareVer(deviceEntity.getFirmwareVer());
        vo.setDeviceName(deviceEntity.getDeviceName());
        vo.setState(deviceEntity.getState());
        vo.setCreateTime(deviceEntity.getCreateTime());
        vo.setUpdateTime(deviceEntity.getUpdateTime());
        return ResponseResultUtil.success(vo);
    }

    @Override
    public DeviceEntity getByImei(String imei) {
        if (StringUtils.isBlank(imei)) {
            return null;
        }
        LambdaQueryWrapper<DeviceEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(DeviceEntity::getImei, imei);
        queryWrapper.eq(DeviceEntity::getState, StatusEnum.VALID.getKey());
        queryWrapper.orderByDesc(DeviceEntity::getCreateTime);
        queryWrapper.last("limit 1");
        return deviceMapper.selectOne(queryWrapper);
    }

    @Override
    public DeviceEntity getByAuthId(Long authId) {
        if (null == authId) {
            return null;
        }
        LambdaQueryWrapper<DeviceEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(DeviceEntity::getAuthId, authId);
        queryWrapper.eq(DeviceEntity::getState, StatusEnum.VALID.getKey());
        queryWrapper.orderByDesc(DeviceEntity::getCreateTime);
        queryWrapper.last("limit 1");
        return deviceMapper.selectOne(queryWrapper);
    }
}
